/**
 * User控制器模块
 * controller\user.js
 *
 */

const express = require("express");

const util = require("../common/util");
/**
 * @typedef {UserDB}
 */
const UserDB = require("../model/sqlite/user");

/**
 * 获取用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function find(req, res) {
    (async function () {
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.find(req.params.id);
        //await db.close();
        util.logFormat(`获取【${req.params.id}】用户信息%O`, result);
        res.json(
            util.FormatJSONData(200, `获取用户信息【${req.params.id}】`, result)
        );
    })();
}

/**
 * 获取用户信息列表
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function findAll(req, res) {
    (async function () {
        //1.处理输入的数据
        //FIXME: 输入数据的正确性校验，一致性校验，完整性校验
        let limit = req.query.limit ? req.query.limit : -1;
        let offset = req.query.offset ? req.query.offset : -1;
        //2. 访问数据
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.findAll(limit, offset);
        //await db.close();
        //3.输出数据
        util.logFormat(`获取【limit=${limit}&offset=${offset}】用户信息%O`, result);
        res.json(util.FormatJSONData(200, `获取用户信息列表`, result));
    })();
}

/**
 * 新增用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function add(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let user = {
            username: req.body.username,
            password: util.md5pwd(req.body.password),
            nickname: req.body.nickname,
            truename: req.body.truename,
            avatar: req.body.avatar,
            role: req.body.role,
            lastLoginTime: 0,
            lastLoginIP: "never login",
            createdTime: Date.now(),
            createdIP: util.getReqRemoteIP(req),
            updatedTime: Date.now(),
        };
        let db = UserDB.getInstance();
        await db.connect();
        //FIXME:插入数据前，考虑校验是否已存在ISBN
        let result = await db.add(user);
        //await db.close();
        util.log(`新增用户信息：lastID->${result}`);
        res.json(util.FormatJSONData(201, `新增用户信息`, {
            lastID: result
        }));
    })();
}

/**
 * 更新用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function update(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let user = {
            id: req.params.id,
            username: req.body.username,
            password: util.md5pwd(req.body.password),
            nickname: req.body.nickname,
            truename: req.body.truename,
            avatar: req.body.avatar,
            role: req.body.role,
            updatedTime: Date.now(),
        };

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.update(user);
        //await db.close();
        util.log(`更新用户信息：changes->${result}`);
        res.json(util.FormatJSONData(200, `更新用户信息`, {
            changes: result
        }));
    })();
}

/**
 * 删除用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function remove(req, res) {
    (async function () {
        //FIXME:数据合法性校验
        let userId = req.params.id;
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.remove(userId);
        //await db.close();
        util.log(`删除用户信息：changes->${result}`);
        res.json(util.FormatJSONData(204, `删除用户信息`, {
            changes: result
        }));
    })();
}

/**
 *获取用户总数
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function getCount(req, res) {
    (async function () {
        //FIXME:数据合法性校验
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.getCount();
        //await db.close();
        util.log(`获取用户总数：${result}`);
        res.json(util.FormatJSONData(200, `获取用户总数`, result));
    })();
}

/**
 * 按关键搜索用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function search(req, res) {
    (async function () {
        //1.处理输入的数据
        //FIXME: 输入数据的正确性校验，一致性校验，完整性校验
        let q = req.query.q;
        let limit = req.query.limit ? req.query.limit : -1;
        let offset = req.query.offset ? req.query.offset : -1;
        //2. 访问数据
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.search(q, limit, offset);
        //await db.close();

        //3.输出数据
        util.logFormat(`获取关键字为【${q}】【limit=${limit}&offset=${offset}】用户信息%O`, result);
        res.json(util.FormatJSONData(200, `获取指定关键字的用户信息列表`, result));
    })();
}

/**
 * 修改个人信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function changeInfo(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let info = {
            nickname: req.body.nickname,
            truename: req.body.truename,
            avatar: req.body.avatar,
        };
        let id = req.session.user.id;

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changeInfo(id, info);
        //await db.close();
        util.log(`修改个人信息：changes->${result}`);
        res.json(util.FormatJSONData(200, `修改个人信息成功`, {
            changes: result
        }));
    })();
}

/**
 * 修改用户密码
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function changePassword(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let password = util.md5pwd(req.body.password);
        let id = req.session.user.id;

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changePassword(id, password);
        //await db.close();
        util.log(`修改用户密码：changes->${result}`);
        res.json(util.FormatJSONData(200, `修改个人密码成功`, {
            changes: result
        }));
    })();
}

/**
 * 重置用户密码
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function resetPassword(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let password = util.md5pwd("123456");
        let id = req.params.id;

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changePassword(id, password);
        //await db.close();
        util.log(`重置用户密码：changes->${result}`);
        res.json(util.FormatJSONData(200, `用户密码重置成功`, {
            changes: result
        }));
    })();
}

/**
 * 注册用户
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function register(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let user = {
            username: req.body.username,
            password: util.md5pwd(req.body.password),
            nickname: req.body.nickname ? req.body.nickname : "",
            truename: req.body.truename ? req.body.truename : "",
            avatar: req.body.avatar ? req.body.avatar : "",
            role: req.body.role,
            lastLoginTime: 0,
            lastLoginIP: "never login",
            createdTime: Date.now(),
            createdIP: util.getReqRemoteIP(req),
            updatedTime: Date.now(),
        };
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.add(user);
        //await db.close();
        util.log(`注册用户信息：lastID->${result}`);
        res.json(util.FormatJSONData(201, `注册用户`, {
            lastID: result
        }));
    })().catch(err => {
        util.log(err);
        res.json(util.FormatJSONData(500, "服务器内容错误", {
            Error: err
        }));
    });
}

/**
 * 用户登录
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function login(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let username = req.body.username;
        let password = util.md5pwd(req.body.password);

        let msg = `用户【${username}】登录失败，请检查用户名和密码`;
        let data = {
            loginStatus: "failed"
        };

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.login(username, password);

        if (result) {
            msg = `用户【${username}】登录成功`;
            data = {
                loginStatus: "success",
                userId: result.id,
                username: result.username,
                nickname: result.nickname,
                truename: result.truename,
                role: result.role,
            };
            let lastLogin = {
                time: Date.now(),
                ip: util.getReqRemoteIP(req),
            };
            await db.touch(username, lastLogin);
            //使用session保存登录状态
            req.session.isLogin = true;
            req.session.user = result;
        }
        //await db.close();
        util.logFormat(`用户【${username}】登录，用户信息%O`, result);
        res.json(util.FormatJSONData(200, msg, data));
        console.log(req.session.user.id);
    })();
}

/**
 * 用户退出
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function logout(req, res) {
    if (req.session.user) {
        let username = req.session.user.username;
        req.session.destroy((err) => util.log(err));
        util.log(`用户【${username}】退出，用户session值【${req.session}】`);
        res.json(
            util.FormatJSONData(200, `用户【${username}】退出系统`, {
                logoutStatus: "success",
            })
        );
    } else {
        res.json(util.FormatJSONData(200, `非正确访问路径`));
    }
}

/**
 * 用户密码校验
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function checkPassword(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let msg = "输入密码与原密码不同！";
        let data = {
            isEqual: false
        };
        let password = util.md5pwd(req.body.password);
        let id = req.session.user.id;

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.find(id);
        //await db.close();
        if (result.password === password) {
            msg = "用户密码校验正确！";
            data.isEqual = true;
        }
        util.log(
            `判断用户【${id}】请求的校验密码【${req.body.password}】，是否相同：【${data.isEqual}】`
        );
        res.json(util.FormatJSONData(200, msg, data));
    })().catch((err) => {
        util.err(err);
        res.json(util.FormatJSONData(500, "服务器发生意外情况，无法完成请求！"));
    });
}



module.exports = {
    find,
    findAll,
    add,
    update,
    remove,
    getCount,
    search,
    changeInfo,
    changePassword,
    resetPassword,
    register,
    login,
    logout,
    checkPassword,
};